package me.liuhui.mall.manager.service.impl;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import me.liuhui.mall.common.base.vo.ResultVO;
import me.liuhui.mall.manager.runtime.AdminSessionHolder;
import me.liuhui.mall.manager.service.PermissionService;
import me.liuhui.mall.manager.service.convertor.PermissionConverter;
import me.liuhui.mall.manager.service.dto.permission.CreatePermissionDTO;
import me.liuhui.mall.manager.service.dto.permission.ModifyPermissionDTO;
import me.liuhui.mall.manager.service.vo.admin.PermissionVO;
import me.liuhui.mall.repository.mapper.PermissionMapper;
import me.liuhui.mall.repository.model.Permission;
import me.liuhui.mall.repository.model.enums.PermissionType;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * Created on 2020/10/14 20:12
 * <p>
 * Description: [TODO]
 * <p>
 * Company: []
 *
 * @author [清远]
 */
@Service
public class PermissionServiceImpl implements PermissionService {
    @Resource
    private PermissionConverter permissionConverter;
    @Resource
    private PermissionMapper permissionMapper;


    @Override
    public List<Permission> currentPermissions(Long adminId) {
        return permissionMapper.selectByAdminId(adminId);
    }


    @Override
    public ResultVO<List<PermissionVO>> menuTree() {
        List<Permission> permissions = AdminSessionHolder.getPermission().stream().filter(permission -> Objects.equals(PermissionType.MENU.getCode(), permission.getType())).distinct().collect(Collectors.toList());
        return ResultVO.success(buildPermissionTree(permissions));
    }

    @Override
    public ResultVO<List<PermissionVO>> permissionTree() {
        List<Permission> permissions = permissionMapper.selectList(null);
        return ResultVO.success(buildPermissionTree(permissions));
    }

    @Override
    public ResultVO<List<PermissionVO>> list() {
        LambdaQueryWrapper<Permission> wrapper = Wrappers.lambdaQuery();
        wrapper.orderByDesc(Permission::getWeight);
        List<Permission> permissions = permissionMapper.selectList(wrapper);
        return ResultVO.success(permissionConverter.toVo(permissions));
    }

    @Override
    public ResultVO<Boolean> create(CreatePermissionDTO dto) {
        LambdaQueryWrapper<Permission> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(Permission::getCode, dto.getCode());
        long count = permissionMapper.selectCount(wrapper);
        if (count > 0) {
            return ResultVO.buildFailResult("权限码已存在！");
        }
        Permission entity = permissionConverter.createDtoToEntity(dto);
        entity.setCreateTime(new Date());
        permissionMapper.insert(entity);
        return ResultVO.success();
    }

    @Override
    public ResultVO<Boolean> modify(ModifyPermissionDTO dto) {
        Permission permission = permissionMapper.selectById(dto.getId());
        if (permission == null) {
            return ResultVO.buildFailResult("权限不存在");
        }
        if (!StrUtil.equals(permission.getCode(), dto.getCode())) {

            LambdaQueryWrapper<Permission> wrapper = Wrappers.lambdaQuery();
            wrapper.eq(Permission::getCode, dto.getCode());
            wrapper.ne(Permission::getId, dto.getId());
            long count = permissionMapper.selectCount(wrapper);
            if (count > 0) {
                return ResultVO.buildFailResult("权限码已存在！");
            }
        }

        Permission entity = permissionConverter.modifyDtoToEntity(dto);
        permissionMapper.updateById(entity);
        return ResultVO.success();
    }

    @Override
    public ResultVO<Boolean> delete(Set<Long> ids) {
        for (Long id : ids) {
            permissionMapper.deleteById(id);
        }
        return ResultVO.success();
    }

    private List<PermissionVO> buildPermissionTree(List<Permission> permissions) {
        List<Permission> tops = permissions.stream().filter(p -> Objects.isNull(p.getPid()) || p.getPid() == -1).collect(Collectors.toList());
        List<PermissionVO> permissionVos = permissionConverter.toVo(tops);
        Collections.sort(permissionVos);
        fillChild(permissionVos, permissions);
        return permissionVos;
    }

    private void fillChild(List<PermissionVO> permissionVos, List<Permission> permissions) {
        permissionVos.forEach(permissionVO -> {
            List<Permission> child = permissions.stream().filter(permission -> Objects.equals(permission.getPid(), permissionVO.getId())).collect(Collectors.toList());
            if (!child.isEmpty()) {
                List<PermissionVO> childen = permissionConverter.toVo(child);
                Collections.sort(childen);
                permissionVO.setChildren(childen);
                fillChild(permissionVO.getChildren(), permissions);
            }
        });
    }
}
